package dal;

import gui.GameConstants;

import java.awt.Dimension;
import java.awt.Point;
import java.io.Serializable;
import java.util.Vector;

import dal.object.*;
import dal.object.grounds.Abyss;

public class MapFileStruct implements Serializable {
	private static final long serialVersionUID = 3L;
	private int startX, startY;    //the map's upper-left corner
	private int ballX, ballY;
	private int cards;
	private Dimension dimension;
	private Dimension size;	// drawing panel's size
	private Vector<Integer> grounds;
	private Vector<Integer> rocks;
	private Vector<Integer> attackers;
	private Vector<Integer> tools;
	private String description;
	private String name;
		
	public MapFileStruct(MapStruct ms) {
		setStructure(ms);
	}
	
	/**
	 * @param ms
	 * 	a MapStruct
	 * converts the structure into a mapFileStruct structure
	 */
	public void setStructure(MapStruct ms){
		this.dimension = ms.getDimension();
		this.size = ms.getSize();
		this.description = ms.getDescription();
		this.name = ms.getName();
		Point ball = ms.getBallPosition();
		this.ballX = ball.x;
		this.ballY = ball.y;
		Point corner = ms.getUpperLeftCorner();
		this.startX = corner.x;
		this.startY = corner.y;
		this.cards = ms.getNumberOfCards();
		
		Ground groundList[] = GameConstants.GROUND_LIST;
		Rock rockList[] = GameConstants.ROCK_LIST;
		Tool toolList[] = GameConstants.TOOL_LIST;
		Attacker attackerList[] = GameConstants.ATTACKER_LIST;
		grounds = new Vector<Integer>();
		rocks = new Vector<Integer>();
		attackers = new Vector<Integer>();
		tools = new Vector<Integer>();
		
		for(MapObject mo : ms.getGroundsVector()){
			if(mo instanceof Abyss){
				grounds.add(-1);
			} else {
				for(int j = 0; j < groundList.length; ++j){
					if(groundList[j].getClass().isAssignableFrom(mo.getClass())){
						grounds.add(j);
						break;
					}
				}
			}
		}
		for(MapObject mo : ms.getRockVector()){
			if(mo == null){
				rocks.add(-1);
			} else {
				for(int j = 0; j < rockList.length; ++j){
					if(rockList[j].getClass().isAssignableFrom(mo.getClass())){
						rocks.add(j);
						break;
					}
				}
			}
		}
		for(MapObject mo : ms.getToolVector()){
			if(mo == null){
				tools.add(-1);
			} else {
				for(int j = 0; j < toolList.length; ++j){
					if(toolList[j].getClass().isAssignableFrom(mo.getClass())){
						tools.add(j);
						break;
					}
				}
			}
		}
		for(MapObject mo : ms.getAttackerVector()){
			if(mo == null){
				attackers.add(-1);
			} else {
				for(int j = 0; j < attackerList.length; ++j){
					if(rockList[j].getClass().isAssignableFrom(mo.getClass())){
						attackers.add(j);
						break;
					}
				}
			}
		}
	}

	//changing the coordinates of the upper-left corner
	public void setUpperLeftCorner(int startX, int startY){
		this.startX = startX;
		this.startY = startY;
	}
	
	//reading the coordinates of the upper-left corner
	public Point getUpperLeftCorner(){
		return new Point(startX, startY);
	}
	
	//reading the coordinates of the ball
	public void setBallPosition(int ballX, int ballY){
		this.ballX = ballX;
		this.ballY = ballY;
	}
	
	//changing the coordinates of the ball
	public Point getBallPosition(){
		return new Point(ballX, ballY);
	}
	
	//reading the the dimension of the map
	public Dimension getDimension(){
		return this.dimension;
	}
	
	// reading drawing panel's size 
	public Dimension getSize() {
		return this.size;
	}
	
	/**
	 * @param descript
	 * 	description of this map
	 */
	public void setDescription(String descript){
		this.description = descript;
	}
	
	/**
	 * @return
 	 * 	description of this map
	 */
	public String getDescription(){
		return this.description;
	}
	
	/**
	 * @return
	 * 	all ground objects in this map
	 */
	public Vector<Integer> getGroundsVector(){
		return grounds;
	}
	
	/**
	 * @return
	 * 	all rock objects in this map
	 */
	public Vector<Integer> getRockVector(){
		return rocks;
	}
	
	public Vector<Integer> getAttackerVector(){
		return attackers;
	}
	
	/**
	 * @return
	 * 	all tool objects in this map
	 */
	public Vector<Integer> getToolVector(){
		return tools;
	}
		
	/**
	 * @param name
	 * 	this map title
	 */
	public void setName(String name) {
		this.name = name;
	}
	
	/**
	 * @return
	 * 	this map title
	 */
	public String getName() {
		return this.name;
	}

	/**
	 * @param cards
	 * 	number of cards in this map
	 */
	public void setNumberOfCards(int cards) {
		this.cards = cards;
	}
	
	/**
	 * @return
	 * 	number of cards in this map
	 */
	public int getNumberOfCards() {
		return cards;
	}
}
